// INCLUDES --------------------------------------------------------------------------------------------------
#include "wallclock.h"

// PLATFORM-SPECIFIC PARTS -----------------------------------------------------------------------------------

#ifdef WIN32
	// Windows
  #include <windows.h>
#endif // WIN32

#ifdef __DARWIN_UNIX03
	// MacOSX
  #include <sys/time.h>
#endif // __DARWIN_UNIX03

// return elapsed milliseconds
ui64 TimeMs()
{
#ifdef WIN32
	return (ui64)timeGetTime();
#endif // WIN32

#ifdef __DARWIN_UNIX03
  static struct timeval t;                             // timeval structure contains seconds+microseconds
	memset(&t, 0, sizeof(t));                            // clear structure
	gettimeofday(&t, NULL);                              // retrieve current time
	return (ui64)(t.tv_sec * 1000 + (t.tv_usec / 1000)); // return elapsed amount of (s+ms)
#endif // __DARWIN_UNIX03

	// in case of non-available functions, return 0
	return 0;
};

// FUNCTIONS -------------------------------------------------------------------------------------------------

// stopwatch function for measuring time intervals in milliseconds
#define STOPWATCH_MAX 1000            // max amount of possible stopwatches
static ui64 stopwatch[STOPWATCH_MAX]; // array of millisecond start times
static bool stopwatchInit = false;    // "array has been cleared once"

// clear stopwatch array values to zero once
static void StopwatchClear()
{
  /* if this is the first time we use the stopwatch functions,
     clear the stopwatch array */
  if (stopwatchInit == false)
  {
    memset(&stopwatch[0], 0, sizeof(stopwatch)); // clear array range
    stopwatchInit = true;                        // mark as "cleared"
  }
};

// START watch X, resetting marked time
void TimeStopwatchStart(ui32 watch)
{
  StopwatchClear();                 // clear stopwatch arry
  CLAMP_HIGH(watch, STOPWATCH_MAX); // clamp array range

  stopwatch[watch] = TimeMs();      // save current ms-time in stopwatch X
};

// STOP watch X, return elapsed millisecond difference
ui64 TimeStopwatchStop(ui32 watch)
{
  StopwatchClear();                          // clear stopwatch arry
  CLAMP_HIGH(watch, STOPWATCH_MAX);          // clamp array range

  if (stopwatch[watch] == 0) return 0;       // return zero, if this stopwatch hasn't been started yet!

  ui64 result = TimeMs() - stopwatch[watch]; // calculate ms-time difference of watch X
  stopwatch[watch] = 0;                      // reset stopwatch X back to 0

  return result;                             // return ms-time difference of stopwatch X
};
